import { getStyle } from '@/utils/DomUtil';
import { animate } from './AnimateUtil';

export default {
  zIndex: 1,
  /** 是否正在运行，防止连续点击 */
  isRunning: false,
  init(wrapElem: HTMLDivElement) {
    const childNodes: any = wrapElem.childNodes;

    // 初始化设置
    for (let nodeItem of childNodes) {
      nodeItem.style.zIndex = this.zIndex;
      this.zIndex += 1;
    }
  },
  change(e: any, wrapElem: HTMLDivElement) {
    const that = this;
    if (this.isRunning) {
      return;
    }
    this.isRunning = true;

    const childNodes: any = wrapElem.childNodes;
    const thisDOM: any = e.target;

    const arr: any = [];
    const baseStartY = thisDOM.offsetTop,
      baseEndY = baseStartY + thisDOM.offsetHeight;
    const baseStartX = thisDOM.offsetLeft,
      baseEndX = baseStartX + thisDOM.offsetWidth;
    const baseCenterX = baseStartX + thisDOM.offsetWidth / 2;
    const baseZIndex = parseInt(getStyle(thisDOM, 'zIndex'));

    const setElemInfo = function (currElem: any) {
      // 整理好四角坐标
      const thisStartY = currElem.offsetTop,
        thisEndY = thisStartY + currElem.offsetHeight;
      const thisStartX = currElem.offsetLeft,
        thisEndX = thisStartX + currElem.offsetWidth;
      const thisCenterX = thisStartX + currElem.offsetWidth / 2;
      const thisZIndex = parseInt(getStyle(currElem, 'zIndex'));
      //依次比较四角坐标
      let flag = false;

      if (thisZIndex > baseZIndex) {
        // 判断窗口是否覆盖的算法
        // 特殊情况
        //       _______    _______          _____
        //   ___|       |  |       |___    _|     |___
        //  |   |       |  |       |   |  | |     |   |
        //  |___|       |  |       |___|  |_|     |___|
        //      |_______|  |_______|        |_____|
        //      _____       ___________      _____
        //   __|_____|__   |           |   _|_____|___
        //  |           |  |           |  |           |
        //  |           |  |___________|  |___________|
        //  |___________|     |_____|       |_____|

        //  常规情况，只要有一个角处于区域内，则可以判断窗口有覆盖
        //   _______            _______        _______    _______
        //  |    ___|___    ___|       |   ___|___    |  |       |___
        //  |   |       |  |   |       |  |       |   |  |       |   |
        //  |___|       |  |   |_______|  |       |___|  |_______|   |
        //      |_______|  |_______|      |_______|          |_______|
        if (
          (thisStartX >= baseStartX &&
            thisStartX <= baseEndX &&
            thisStartY >= baseStartY &&
            thisStartY <= baseEndY) ||
          (thisStartX >= baseStartX &&
            thisStartX <= baseEndX &&
            thisEndY >= baseStartY &&
            thisEndY <= baseEndY) ||
          (thisEndX >= baseStartX &&
            thisEndX <= baseEndX &&
            thisStartY >= baseStartY &&
            thisStartY <= baseEndY) ||
          (thisEndX >= baseStartX &&
            thisEndX <= baseEndX &&
            thisEndY >= baseStartY &&
            thisEndY <= baseEndY)
        ) {
          flag = true;
        }

        //  非常规情况
        //       _______    _______          _____
        //   ___|       |  |       |___    _|     |___
        //  |   |       |  |       |   |  | |     |   |
        //  |___|       |  |       |___|  |_|     |___|
        //      |_______|  |_______|        |_____|

        if (
          (thisStartX >= baseStartX &&
            thisStartX <= baseEndX &&
            thisStartY < baseStartY &&
            thisEndY > baseEndY) ||
          (thisEndX >= baseStartX &&
            thisEndX <= baseEndX &&
            thisStartY < baseStartY &&
            thisEndY > baseEndY)
        ) {
          flag = true;
        }

        //      _____       ___________      _____
        //   __|_____|__   |           |   _|_____|___
        //  |           |  |           |  |           |
        //  |           |  |___________|  |___________|
        //  |___________|     |_____|       |_____|
        if (
          (thisStartY >= baseStartY &&
            thisStartY <= baseEndY &&
            thisStartX < baseStartX &&
            thisEndX > baseEndX) ||
          (thisEndY >= baseStartY &&
            thisEndY <= baseEndY &&
            thisStartX < baseStartX &&
            thisEndX > baseEndX)
        ) {
          flag = true;
        }

        if (
          thisStartX >= baseStartX &&
          thisStartX <= baseEndX &&
          thisStartY >= baseStartY &&
          thisStartY <= baseEndY
        ) {
          flag = true;
        } else if (
          thisStartX >= baseStartX &&
          thisStartX <= baseEndX &&
          thisEndY >= baseStartY &&
          thisEndY <= baseEndY
        ) {
          flag = true;
        } else if (
          thisEndX >= baseStartX &&
          thisEndX <= baseEndX &&
          thisStartY >= baseStartY &&
          thisStartY <= baseEndY
        ) {
          flag = true;
        } else if (
          thisEndX >= baseStartX &&
          thisEndX <= baseEndX &&
          thisEndY >= baseStartY &&
          thisEndY <= baseEndY
        ) {
          flag = true;
        }
      }

      if (flag) {
        let direction, distance;
        if (thisCenterX > baseCenterX) {
          direction = 'right';
          distance = baseEndX - thisStartX + 30;
        } else {
          direction = 'left';
          distance = thisEndX - baseStartX + 30;
        }

        arr.push({
          elem: currElem,
          class: thisDOM.getAttribute('class'),
          direction: direction, // 移动方向
          distance: distance, // 移动距离
        });
      }
    };

    for (let nodeItem of childNodes) {
      setElemInfo(nodeItem);
    }

    //开始移动
    let delayTime = 0;
    for (let i = 0; i < arr.length; i++) {
      const elemItem = arr[i].elem;
      const baseLeft = elemItem.offsetLeft;

      if (arr[i].direction == 'left') {
        const oldAnimateJson: any = {
          left: baseLeft - arr[i].distance,
        };
        const newAnimateJson: any = {
          left: baseLeft,
        };

        animate(
          elemItem,
          oldAnimateJson,
          300,
          () => {
            animate(elemItem, newAnimateJson, 300);
          },
          'easeInOutQuad',
        );
      } else {
        const oldAnimateJson: any = {
          left: baseLeft + arr[i].distance,
        };
        const newAnimateJson: any = {
          left: baseLeft,
        };

        animate(
          elemItem,
          oldAnimateJson,
          300,
          () => {
            animate(elemItem, newAnimateJson, 300);
          },
          'easeInOutQuad',
        );
      }
      delayTime += 100;
    }

    setTimeout(function () {
      thisDOM.style.zIndex = that.zIndex;
      that.zIndex += 1;
      that.isRunning = false;
    }, delayTime + 100);
  },
};
